/**
 * 
 */
package qy.jalgotrade.strategy.position;

import java.util.Arrays;

import com.google.common.math.DoubleMath;

import qy.jalgotrade.broker.Order;
import qy.jalgotrade.broker.OrderEvent;
import qy.jalgotrade.utils.CommonUtils;

/**
 * @author c-geo
 *
 */
public class WaitingEntryState extends PositionState {

	/**
	 * 
	 */
	public WaitingEntryState() {

	}

	/* (non-Javadoc)
	 * @see qy.jalgotrade.strategy.position.PositionState#onEnter(qy.jalgotrade.strategy.position.Position)
	 */
	@Override
	public void onEnter(Position position) {

	}

	/* (non-Javadoc)
	 * @see qy.jalgotrade.strategy.position.PositionState#canSubmitOrder(qy.jalgotrade.strategy.position.Position, qy.jalgotrade.broker.Order)
	 */
	@Override
	public void canSubmitOrder(Position position, Order order) throws Exception {

		if (position.entryActive()) {
			throw new Exception("The entry order is still active");
		}
	}

	/* (non-Javadoc)
	 * @see qy.jalgotrade.strategy.position.PositionState#onOrderEvent(qy.jalgotrade.strategy.position.Position, qy.jalgotrade.event.Event)
	 */
	@Override
	public void onOrderEvent(Position position, OrderEvent orderEvent) throws Exception {

		// Only entry order events are valid in this state.
		assert position.getEntryOrder().getId().equals(orderEvent.getOrder().getId());

		if (Arrays.asList(OrderEvent.Type.FILLED, OrderEvent.Type.PARTIALLY_FILLED)
		        .contains(orderEvent.getEventType())) {

			position.switchState(new OpenState());
			position.getStrategy().onEnterOk(position);

		} else if (orderEvent.getEventType() == OrderEvent.Type.CANCELED) {

			assert DoubleMath.fuzzyEquals(position.getEntryOrder().getFilled(), 0, CommonUtils.FUZZY_EQUAL_TOLERANCE_MATH);
			position.switchState(new ClosedState());
			position.getStrategy().onEnterCanceled(position);
		}
	}

	/* (non-Javadoc)
	 * @see qy.jalgotrade.strategy.position.PositionState#isOpen(qy.jalgotrade.strategy.position.Position)
	 */
	@Override
	public boolean isOpen(Position position) {

		return true;
	}

	/* (non-Javadoc)
	 * @see qy.jalgotrade.strategy.position.PositionState#exit(qy.jalgotrade.strategy.position.Position, double, double, boolean)
	 */
	@Override
	public void exit(Position position, double stopPrice, double limitPrice, boolean goodTillCanceled) throws Exception {

		assert DoubleMath.fuzzyEquals(position.getShares(), 0, CommonUtils.FUZZY_EQUAL_TOLERANCE_MATH);
		assert position.getEntryOrder().isActive();
		position.getStrategy().getBroker().cancelOrder(position.getEntryOrder());
	}
}
